package display;

import interfaces.IDisplayObserver;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

/**
 * @author Stefano&Davide
 * @version 1.0
 */

public class DisplayGuiOdometerObserverThreadListener extends Thread {

	private IDisplayObserver display;

	public DisplayGuiOdometerObserverThreadListener(DisplayGuiOdometerObserver disp){
		display=disp;
	}
	
	@Override
	public void run(){
		DatagramSocket socket = null;
		DatagramPacket packet = null;
		byte[] buf = new byte[256];
		String valToDisplay=null;

		// inizializzazione socket e strutture dati di supporto
		try {
			socket = new DatagramSocket(display.getRemoteNode().getPort());
			packet = new DatagramPacket(buf, buf.length);
			System.out.println("Creata la socket: " + socket);
		} catch (SocketException e) {
			System.out.println("Problemi nella creazione della socket: ");
			e.printStackTrace();
			System.exit(1);
		}

		// relizzazione logica di servizio
		try {
			// dichiarazione oggetti per la lettura/scrittura dei dati come stream di
			// byte nel pacchetto UDP
			ByteArrayInputStream biStream = null;
			DataInputStream diStream = null;
			ByteArrayOutputStream boStream = null;
			DataOutputStream doStream = null;
			byte[] data = null;

			// QUI DICHIARAZIONE DI VARIABILI NECESSARIE PER LA REALIZZAZIONE
			// DELLA LOGICA DEL PROGRAMMA
			while (true) {
				System.out.println("\nIn attesa di richieste...");

				// ricezione del datagramma
				try {
					packet.setData(buf);
					socket.receive(packet);
				} catch (IOException e) {
					System.err.println("Problemi nella ricezione del datagramma: "
							+ e.getMessage());
					e.printStackTrace();
					continue;
					// il server continua a fornire il servizio ricominciando dall'inizio
					// del ciclo
				}

				try {
					biStream = new ByteArrayInputStream(packet.getData(), 0, packet
							.getLength());
					diStream = new DataInputStream(biStream);
					// QUI ESTRAZIONE RICHIESTA DALLO STREAM DI INPUT
					// ad esempio, per la lettura della stringa 
					valToDisplay=diStream.readUTF();
				} catch (Exception e) {
					System.err.println("Problemi nella lettura della richiesta: ");
					e.printStackTrace();
					continue;
					// il server continua a fornire il servizio ricominciando dall'inizio
					// del ciclo
				}

				// Realizzazione logica di programma e invio della risposta
				try {
					// QUI LOGICA PER LA REALIZZAZIONE DELLE FUNZIONALITA' RICHIESTE
					if(valToDisplay!=null){
						boStream = new ByteArrayOutputStream();
						doStream = new DataOutputStream(boStream);
						display.update(valToDisplay);
						// QUI INSERIMENTO DATI DI INPUT NELLO STREAM DI OUTPUT
						doStream.writeUTF("Ok");

						// inserimento dati nel pacchetto UDP
						data = boStream.toByteArray();
						packet.setData(data, 0, data.length);

						// invio pacchetto UDP al pari
						socket.send(packet);
					}
				} catch (IOException e) {
					System.err.println("Problemi nell'invio della risposta: "
							+ e.getMessage());
					e.printStackTrace();
					continue;
					// il server continua a fornire il servizio ricominciando dall'inizio
					// del ciclo
				}

			} // while

		}
		// qui catturo le eccezioni non catturate all'interno del while
		// in seguito alle quali il server termina l'esecuzione
		catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println("UDP_Unicast_Server: termino...");
		socket.close();
	}
}


